<?php


namespace app\msgapi\service;

use app\msgapi\model\FileList;
use think\facade\Log;

error_reporting(E_ERROR | E_PARSE);
class FileHandleService
{

    public function fileDown($sdkId, $info, $basedir = '')
    {
        //是混合消息
        if ($info['mstype'] == 'mixed') {
            return $this->handlesMixed($sdkId, $info, $basedir);
        }
        //是会话消息记录
        if ($info['mstype'] == 'chatrecord') {
            return $this->handleChatRecord($sdkId, $info, $basedir);
        }
        //其他标准消息
        return $this->handleStatcChat($sdkId, $info, $basedir);
    }


    /**是会话消息记录
     * @param $sdkId
     * @param $info
     * @param string $basedir
     * @return mixed
     * @throws \Exception
     */
    function handleChatRecord($sdkId, $info, $basedir = '')
    {
//        Log::write('会话消息记录','info');
        $filelist = json_decode($info['filelist'], true);
        foreach ($filelist as $key => $val) {
            $filepath = $this->fileDownload($sdkId, $key, $val['fileext'], $val['sdkfileid'], date('Ymd', strtotime($info['msgtime'])), $basedir);
            $filelist[$key]['filepath'] = $filepath['filename'];
        }
        $info['filelist'] = json_encode($filelist, 256);
        $info['isgetfile'] = 3;
        return $info;
    }


    /**其他标准消息
     * @param $sdkId
     * @param $info
     * @param string $basedir
     * @return mixed
     * @throws \Exception
     */
    function handleStatcChat($sdkId, $info, $basedir = '')
    {
//        Log::write('其他标准消息','info');
        $msgbody = json_decode($info['msgbody'], true);
        $fileExt = '';
        switch ($info['mstype']) {
            case 'image':
                $fileExt = 'png';
                break;
            case "video":
                $fileExt = 'mp4';
                break;
            case "meeting_voice_call":
                $fileExt='mp3';
                break;
            case 'voice':
                $fileExt = 'amr';
                break;
            case "emotion":
                $msgbody['type'] == 1 ? $fileExt = 'gif' : $fileExt = 'png';
                break;
            case "file":
                $fileExt = $msgbody['fileext'];
                break;
            case "voip_doc_share":
                $fileexpload = explode('.', $msgbody['filename']);
                $fileExt = end($fileexpload);
                break;
        }
        if ($fileExt) {
            $fileinfo = $this->fileDownload($sdkId, $msgbody['md5sum'], $fileExt, $msgbody['sdkfileid'], date('Ymd', strtotime($info['msgtime'])), $basedir);
            $filepath = $fileinfo['filename'];
            if ($filepath) {
                $info['filepath'] = $filepath;
                $info['isgetfile'] = 3;
            }
        }
        return $info;
    }

    function handlesMixed($sdkId, $info, $basedir = '')
    {
//        Log::write('混合消息','info');
        $msgbody = json_decode($info['msgbody'], true);
        foreach ($msgbody['item'] as $key => $value) {
            $data = json_decode($value['content'], true);
            if ($value['type'] == 'emotion') {
                $data['type'] == 1 ? $fileext = 'gif' : $fileext = 'png';
            } else if ($value['type'] == 'image') {
                $fileext = 'png';
            } else {
                $fileext = '';
            }
            if ($fileext != '') {
                $fileinfo = $this->fileDownload($sdkId, $data['md5sum'], $fileext, $data['sdkfileid'], date('Ymd', strtotime($info['msgtime'])), $basedir);
                $filepath = $fileinfo['filename'];
                if ($filepath) {
                    $msgbody['item'][$key]['filepath'] = $filepath;
                }
            }
        }
        $info['msgbody'] = json_encode($msgbody, 256);
        $info['isgetfile'] = 3;
        return $info;
    }


    /**下载文件
     * @param $sdkId string SDKID
     * @param $fileext string 文件类型
     * @param $sdkfileid string sdkfileid
     * @param string $date 存储路径
     * @param string $basedir 基础路径
     * @return array|boolean
     * @throws \Exception
     */
    function fileDownload($sdkId, $md5sum, $fileext, $sdkfileid, $date = '', $basedir = '')
    {
        $md5sum?:$md5sum = md5($sdkfileid);
        $fileListModel = new FileList();
        $fileexits = $fileListModel->where('md5sum',$md5sum)->findOrEmpty()->toArray();
        $filelistData = [];
        $res = true;
        if ($fileexits['filepath']) {
            $filename = $fileexits['filepath'];
        } else {
            $next = true;
            $indexbuf = '';
            $filedir = '/storage/wxfile/' . $date;
            if (!is_dir($basedir . $filedir)) {
                mkdir($basedir . $filedir, 0755, true);
            }
            $filename = $filedir . '/' . $md5sum . '.' . $fileext;
            //如果文件已经存在，则证明之前传过此文件中断，需要将原中断文件删除
            if (file_exists($basedir . $filename)) {
                unlink($basedir . $filename);
            }
            while ($next) {
                $javaPullMsgApiService = new JavaPullMsgApiService();
                $data = $javaPullMsgApiService->getMediaData($sdkId, $indexbuf, $sdkfileid);
                if ($data['code'] == 0) {
                    $file = base64_decode($data['data']['data']);
                    $res = file_put_contents($basedir . $filename, $file, FILE_APPEND);
                    if ($data['data']['end']) {
                        $next = false;
                    } else {
                        $next = true;
                        $indexbuf = $data['data']['indexbuf'];
                    }
                } else {
                    $next = false;
                }
            }
            $filelistData['filepath'] = $filename;
            $filelistData['filesize'] = filesize( $basedir . $filename);
        }

        if ($filelistData) {
            $filelistData['md5sum'] = $md5sum;
            $fileexits ? $fileListModel->where('md5sum', $md5sum)->update($filelistData) : $fileListModel->create($filelistData);
        }
        if ($res) {
            return compact('filename');
        } else {
            return false;
        }
    }
}